from pydantic import BaseModel, Field
from pymongo import MongoClient
from bson import ObjectId
from typing import Optional


myclient = MongoClient('mongodb://localhost:27017/')
db = myclient["DPLibrary"]


class PyObjectId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not ObjectId.is_valid(v):
            raise ValueError('Invalid objectid')
        return ObjectId(v)

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(type='string')


class Cards(BaseModel):
    '''
    借阅证基本模型「对应数据库的cards集合」
    '''
    id: Optional[PyObjectId] = Field(alias='_id')
    card_id: str
    reader_name: str
    reader_sex: str
    reader_id: str
    create_date: str
    reader_type: str
    unit_name: str
    max_borr: int
    debt_count: float
    phone_num: str
    available_status: bool

    class Config:
        arbitrary_types_allowed = True
        json_encoders = {
            ObjectId: str
        }


class CardCreate(BaseModel):
    '''
    借阅证创建接口模型
    '''
    card_id: str
    reader_name: str
    reader_sex: str
    reader_id: str
    create_date: str
    reader_type: str
    unit_name: str
    phone_num: str
class CardsQueryDetail(BaseModel):
    card_id: Optional[str] = ""
    reader_name: Optional[str] = ""
    reader_sex: Optional[str] = ""
    reader_id: Optional[str] = ""
    reader_type: Optional[str] = ""
    unit_name: Optional[str] = ""
    phone_num: Optional[str] = ""
    available_status: Optional[bool] = None

class CardsQuery(BaseModel):
    '''
    借阅证查询接口模型
    page：页数
    size：每页数据条数
    '''
    card_id:  Optional[str] = ""
    reader_name: Optional[str] = ""
    reader_sex: Optional[str] = ""
    reader_id: Optional[str] = ""
    reader_type: Optional[str] = ""
    unit_name: Optional[str] = ""
    phone_num: Optional[str] = ""
    available_status: Optional[bool] = None
    page: Optional[int] = 1
    size: Optional[int] = 10


class Book(BaseModel):
    '''
    图书基本模型「对应数据库的books集合」
    '''
    id: Optional[PyObjectId] = Field(alias='_id')
    book_id: Optional[str]
    book_name: Optional[str]
    book_author: Optional[str]
    publisher: Optional[str]
    pub_date: Optional[str]
    page_count: Optional[int] = Field(ge=0)
    book_price: Optional[float]
    isbn: Optional[str]
    available_status: Optional[bool]

    class Config:
        arbitrary_types_allowed = True
        json_encoders = {
            ObjectId: str
        }


class BookCreate(BaseModel):
    '''
    图书创建接口模型
    '''
    book_id: str
    book_name: str
    book_author: str
    publisher: str
    pub_date: str
    page_count: int = Field(ge=0)
    book_price: float
    isbn: str


class BookQuery(BaseModel):
    '''
    图书查询接口模型
    page：页数
    size：每页数据条数
    '''
    book_id: Optional[str] = ""
    book_name: Optional[str] = ""
    book_author: Optional[str] = ""
    publisher: Optional[str] = ""
    pub_date: Optional[str] = ""
    isbn: Optional[str] = ""
    available_status: Optional[bool] = None
    page: Optional[int] = 1
    size: Optional[int] = 10


class BorrowInfo(BaseModel):
    '''
    借阅信息基本模型「对应数据库的borrow_info集合」
    '''
    id: Optional[PyObjectId] = Field(alias='_id')
    book_id: str
    book_name: str
    card_id: str
    reader_name: str
    renew_num: Optional[str]
    borr_date: str
    due_date: str
    return_date: Optional[str]
    return_status: bool

class FineInfo(BaseModel):
    '''
    罚款信息基本模型「对应数据库的fine_info集合」
    '''
    id: Optional[PyObjectId] = Field(alias='_id')
    book_id: str
    book_name: str
    card_id: str
    reader_name: str
    borr_date: str
    due_date: str
    need_pay: float
    paid_in: Optional[float]
    handle_status: bool

class BorrowInfoQuery(BaseModel):
    '''
    借阅信息查询接口模型
    page：页数
    size：每
    '''
    book_id: str=""
    book_name: str=""
    card_id: str=""
    reader_name: str=""
    return_status: str=""
    page: Optional[int] = 1
    size: Optional[int] = 10


class FineQuery(BaseModel):
    '''
    罚款查询接口模型
    page：页数
    size：每页数据条数
    根据card_id 查询超期罚款人罚款记录
    '''
    book_id: Optional[str] = ""
    book_name: Optional[str] = ""
    card_id: Optional[str] = ""
    reader_name: Optional[str] = ""
    borr_date: Optional[str] = ""
    due_date: Optional[str] = ""
    handle_status: Optional[bool] = None
    page: Optional[int] = 1
    size: Optional[int] = 10
